/**
 * @author zhoukailiang
 * @data 2012-05-19
 */
(function($) {
	// 是否有水平滚动条
	var hasXScroll;
	// 是否有垂直滚动条
	var hasYScroll;
	// 滚动条的宽度
	var scrollW;
	// 冻结行数
	var freezeRow;
	// 冻结列数
	var freezeCell;
	// 当前要冻结对象容器
	var freeze;
	var freezeTab;
	var timestamp;
	function freezeInit(event) {
		if (event) {
			freeze = event.data.freeze;
			freezeTab = event.data.freezeTab;
			timestamp = event.data.time;
		}

		var freezeH = freeze.outerHeight(true);
		var freezeW = freeze.outerWidth(true);
		var tabW = freezeTab.outerWidth(true);
		var tabH = freezeTab.outerHeight(true);

		var freezeoffset = freeze.offset();
		var freezeDom = freeze[0];
		scrollW = freezeDom.offsetWidth - freezeDom.clientWidth
		if (scrollW == 0) {
			scrollW = freezeDom.offsetHeight - freezeDom.clientHeight;
		}
		//兼容FireFox容器刚好滚动条的宽度不显示问题
		if(($.browser.mozilla) && scrollW > 5){
			scrollW +=0.5;
		}
		var xtop = (freezeoffset.top + freezeH - scrollW)
		var xleft = freezeoffset.left;
		var ytop = (freezeoffset.top);
		var yleft = (freezeoffset.left + freezeW - scrollW);

		// 通过判断容器的高是否一致 来确定是否有X轴上的滚动条
		hasXScroll = freezeDom.offsetHeight > freezeDom.clientHeight;
		// 通过判断容器的宽
		hasYScroll = freezeDom.offsetWidth > freezeDom.clientWidth;

		if (hasXScroll && hasYScroll) {
			freezeH -= scrollW;
			freezeW -= scrollW;
		}

		if (hasXScroll) {
			createXScroll();
			$("#xscroll" + timestamp).css({
						'overflow-x' : 'scroll',
						'position' : 'absolute',
						'z-index' : 105,
						'overflow-y' : 'hidden',
						width : freezeW + "px",
						height : scrollW + 'px',
						top : xtop + 'px',
						left : xleft + 'px'
					});
			$("#xscroll" + timestamp + " div").css({
						width : freezeTab.outerWidth() + 'px',
						height : scrollW + 'px',
						filter : 'alpha(opacity=100)'
					});
		}
		if (hasYScroll) {
			createYScroll();
			$("#yscroll" + timestamp).css({
						'overflow-y' : 'scroll',
						'position' : 'absolute',
						'z-index' : 105,
						'overflow-x' : 'hidden',
						height : freezeH + "px",
						width : scrollW + 'px',
						top : ytop + 'px',
						left : yleft + 'px'
					});
			$("#yscroll" + timestamp + " div").css({
						height : tabH + 'px',
						width : scrollW + 'px',
						filter : 'alpha(opacity=100)'
					});
		}
	};
	function createYScroll() {
		$("#yscroll" + timestamp).remove();
		var yscroll = $("<div id='yscroll" + timestamp + "'>");
		var yb = $("<div>");
		yscroll.append(yb);
		freeze.parent().append(yscroll);
		yscroll.bind('scroll', {
					time : timestamp,
					freeze : freeze
				}, scroll);
	}

	function createXScroll() {
		$("#xscroll" + timestamp).remove();
		var xscroll = $("<div id='xscroll" + timestamp + "'>");
		var xb = $("<div>");
		xscroll.append(xb);
		freeze.parent().append(xscroll);
		xscroll.bind('scroll', {
					time : timestamp,
					freeze : freeze
				}, scroll);
	}
	function scroll(event) {
		timestamp = event.data.time;
		freeze = event.data.freeze;
		if ($("#xscroll" + timestamp)) {
			var leftx = $("#xscroll" + timestamp).scrollLeft()
			$("#freeze_head" + timestamp).scrollLeft(leftx);
			freeze.scrollLeft(leftx);
		}
		if ($("#yscroll" + timestamp)) {
			var topx = $("#yscroll" + timestamp).scrollTop()
			$("#freeze_left" + timestamp).scrollTop(topx);
			freeze.scrollTop(topx);
		}
	}
	function initContiner(event) {
		if (event) {
			freeze = event.data.freeze;
			freezeTab = event.data.freezeTab;
			timestamp = event.data.time;
		}
		var ie = $.browser.msie;
		var offset = freeze.offset();
		var offsetTab = freezeTab.offset();
		var top = Math.round(offsetTab.top);
		var left = Math.round(offsetTab.left);
		var width = freeze.outerWidth(true);
		var height = freeze.outerHeight(true);
		// 需要计算的值
		// top层的宽高变量
		var topH = 0;
		var topW = 0;
		// 边框宽高变量
		var borderW;
		var borderH;
		var rows = freezeTab.find("tr");
		var cells = rows.find("th");
		// 获取行边框像素
//		if(ie || $.browser.opera){
			borderH = freezeTab.find('tr').offset().left;
			borderW = borderH
//		}
//		else{
//			borderH = freezeTab.outerHeight(true) - freezeTab.height();
//			borderW = freezeTab.outerWidth(true) - freezeTab.width();
//		}
//		alert(borderH +" @ "+borderW);
		// 计算top层的高度
		for (var i = 0; i < freezeCell; i++)
			topW += $(cells[i]).width()+borderW;
		for (var i = 0; i < freezeRow; i++)
			topH += $(rows[i]).height()+borderH;
		if(!ie){
			topW -=borderW >>1;
		}
		topH -=borderH >> 1;
		
		var topTabH = topH;
		var leftRow = $("#freeze_left" + timestamp + ">table").eq(0).find('tr');
		var topRow = $("#freeze_top" + timestamp + ">table").eq(0).find('tr');
		rows.each(function(index, ele) {
					var _eleH =  ie?$(ele).height():ele.clientHeight;//
					leftRow.eq(index).css({height : _eleH });
					topRow.eq(index).css({ height : _eleH });
				});
		// 设置Head 行的列宽度
		var headCells = $("#freeze_head" + timestamp + ">table").find("tr>th")
		var topCells = $("#freeze_top" + timestamp + ">table").eq(0).find('tr>th');;
		var leftCells = $("#freeze_left" + timestamp + ">table").eq(0).find('tr>th');;
		var _tabCells = freezeTab.find('tr>th');

		cells.each(function(index, elm) {
					var _elmW = ie?elm.clientWidth:$(elm).width() ;//
					var _elmOffset = $(elm).offset();
					leftCells.eq(index).css({ width : _elmW });
					headCells.eq(index).css({ width : _elmW });
					topCells.eq(index).css({ width : _elmW });
					_tabCells.eq(index).css({width : _elmW});
				});
		var headH = topH;
		var leftH = height;
		var headW = width;
		var leftW = $("#freeze_top" + timestamp + ">table").outerWidth(true);//topW;

		if (hasXScroll && hasYScroll) {
			headW = (width - scrollW);
			leftH = (height - scrollW);
		} else if (hasYScroll) {
			headW = (width - scrollW);
		} else if (hasXScroll) {
			leftH = (height - scrollW);
		}
		// alert(topW +":"+borderW+":"+borderH);
		// alert(freezeTab.width()+":"+freezeTab.outerWidth()+":"+freezeTab.innerWidth());
		// 设置Css样式
		var _offset = {top:top,left:left}//offsetTab;//{top:(top+borderH),left:(left+borderW)};
		$("#freeze_top" + timestamp).css(getCss(topW, topH, 105, top, left))
				.offset(_offset);
		$("#freeze_head" + timestamp).css(getCss(headW, topH, 104, top, left))
				.offset(_offset);
		$("#freeze_left" + timestamp).css(getCss(topW, leftH, 104, top, left))
				.offset(_offset);

		$("#freeze_top" + timestamp + ">table").css(getCss(topW, topTabH, 105,
				0, 0))
		$("#freeze_head" + timestamp + ">table").css(getCss(freezeTab
						.outerWidth(), topTabH, 104, 0, 0))
		$("#freeze_left" + timestamp + ">table").css(getCss(topW, height, 104,
				0, 0))
		freezeTab.offset(_offset);
	}
	function getCss(width, height, zindex, left, top) {
		return {
			position : 'absolute',
			'background-color' : '#FFFFFF',
			overflow : 'hidden',
			opacity : '1',
			left : left + 'px',
			top : top + 'px',
			width : width + 'px',
			height : height + 'px',
			'z-index' : zindex
		};
	}
	function getTabContianers(tab, row, cell) {
		var contis = new Array();
		if (row == 0 && cell == 0) {
			return contis;
		}
		var tabClone = tab.clone();
		tabClone.attr("id", '');
		var headContainer = $("<div>");
		var topContianer = headContainer.clone();
		var leftContianer = headContainer.clone();

		topContianer.attr("id", 'freeze_top' + timestamp);
		headContainer.attr("id", 'freeze_head' + timestamp);
		leftContianer.attr("id", 'freeze_left' + timestamp);

		var headTab = tabClone.clone().empty();
		var topTab = headTab.clone();
		var leftTab = headTab.clone();

		var rows = tabClone.find("tr");
		for (var i = 0; i < rows.length; i++) {
			var currRow = rows.eq(i);
			if (i < row) {
				headTab.append(currRow);
			}
			if (cell > 0) {
				var currLeftRow = currRow.clone().empty();
				var currCells = currRow.clone().children();
				for (var j = 0; j < cell; j++) {
					currLeftRow.append($(currCells[j]));
				}
				leftTab.append(currLeftRow);
			}
			if (cell > 0 && row > i) {
				var currTopRow = currRow.clone();
				var currCells = currTopRow.children();
				for (var j = cell; j < currCells.length; j++) {
					$(currCells[j]).remove();
				}
				topTab.append(currTopRow);
			}
		}

		topContianer.append(topTab);
		headContainer.append(headTab);
		leftContianer.append(leftTab);
		if (row > 0 && cell > 0) {
			contis[0] = headContainer;
			contis[1] = leftContianer;
			contis[2] = topContianer;
			return contis;
		}
		if (row > 0) {
			contis[0] = headContainer;
		}
		if (cell > 0) {
			contis[0] = leftContianer;
		}
		return contis;
	}
	jQuery.fn.freeze = function(row, cell) {
		timestamp = new Date().getTime();
		freezeTab = $(this);
		freeze = $(this).parent();
		var tab = freezeTab
		if (tab.length == 0) {
			return;
		}
		freezeRow = row;
		freezeCell = cell;
		freezeInit();

		$(getTabContianers(tab, row, cell)).each(function() {
					freeze.append(this)
				});
		initContiner();
		var data = {
			time : timestamp,
			freeze : freeze,
			freezeTab : freezeTab
		};
		freeze.bind("scroll", data, scroll);

		$(window).bind("resize", data, freezeInit);
		$(window).bind("resize", data, initContiner);
	}
})(jQuery);
